package com.dlc.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlc.shop.allinpay.service.AllinpayCompanyService;
import com.dlc.shop.bean.dto.OrderRefundDto;
import com.dlc.shop.bean.enums.*;
import com.dlc.shop.bean.event.RefundInfoEvent;
import com.dlc.shop.bean.model.*;
import com.dlc.shop.bean.param.CustomerReqParam;
import com.dlc.shop.bean.pay.RefundInfoDto;
import com.dlc.shop.bean.vo.AccountDetailVO;
import com.dlc.shop.bean.vo.ShopAccountDetailVO;
import com.dlc.shop.bean.vo.ShopAccountVO;
import com.dlc.shop.common.allinpay.constant.PaySysType;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.enums.PayType;
import com.dlc.shop.common.util.Arith;
import com.dlc.shop.common.util.IpHelper;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.dao.OrderRefundMapper;
import com.dlc.shop.dao.PayInfoMapper;
import com.dlc.shop.dao.RefundInfoMapper;
import com.dlc.shop.huifu.DemoTestConstants;
import com.dlc.shop.manager.impl.AllinpayManager;
import com.dlc.shop.manager.impl.PayManager;
import com.dlc.shop.service.*;
import lombok.AllArgsConstructor;
import org.apache.ibatis.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author Citrus
 * @date 2022-05-25 15:45:45
 */
@Service
@AllArgsConstructor
public class RefundInfoServiceImpl extends ServiceImpl<RefundInfoMapper, RefundInfo> implements RefundInfoService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final RefundInfoMapper refundInfoMapper;
    private final PayInfoMapper payInfoMapper;
    private final PayManager payManager;
    private final AllinpayManager allinpayManager;
    private final ApplicationEventPublisher eventPublisher;
    private final AllinpayCompanyService allinpayCompanyService;


    private final OrderService orderService;
    private final OrderItemService orderItemService;
    private final OrderRefundMapper orderRefundMapper;
    private final SkuService skuService;
    private final ShopDetailService shopDetailService;


    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean doRefund(RefundInfoDto refundInfoDto) {
        logger.info("退款 refundInfoDto 接收到的参数{}",refundInfoDto);
        if (count(new LambdaQueryWrapper<RefundInfo>().eq(RefundInfo::getRefundId, refundInfoDto.getRefundSn())) > 0) {
            return false;
        }
        PayInfo payInfo = payInfoMapper.selectOne(new LambdaQueryWrapper<PayInfo>().eq(PayInfo::getPayNo, refundInfoDto.getPayNo()));
        if (Objects.isNull(payInfo)) {
            return false;
        }
        List<RefundInfo> refundInfoList = new ArrayList<>();
        for (String refundOrderNumber : refundInfoDto.getRefundOrderNumbers()) {
            RefundInfo refundInfo = new RefundInfo();
            refundInfo.setRefundId(refundInfoDto.getRefundSn());
            refundInfo.setRefundAmount(refundInfoDto.getRefundAmount());
            refundInfo.setOrderNumber(refundOrderNumber);
            refundInfo.setPayNo(refundInfoDto.getPayNo());
            refundInfo.setPayType(payInfo.getPayType());
            refundInfo.setUserId(payInfo.getUserId());
            refundInfo.setRefundStatus(RefundStatusEnum.APPLY.value());
            refundInfo.setRefundType(refundInfoDto.getRefundType());
            refundInfo.setReqDate(refundInfoDto.getReqDate());
            refundInfoList.add(refundInfo);
        }
        // 保存退款信息 refund_id是唯一的，所以能确保只进行一次退款
        saveBatch(refundInfoList);

        RefundInfoDto returnRefundInfo = new RefundInfoDto();
        returnRefundInfo.setBizUserId(refundInfoDto.getBizUserId());
        returnRefundInfo.setPayNo(refundInfoDto.getPayNo());
        returnRefundInfo.setRefundSn(refundInfoDto.getRefundSn());
        returnRefundInfo.setPayType(PayType.instance(payInfo.getPayType()));
        returnRefundInfo.setPayAmount(payInfo.getPayAmount());
        returnRefundInfo.setRefundAmount(refundInfoDto.getRefundAmount());
       // returnRefundInfo.setNotifyUrl("/order/refund/result/" + payInfo.getPaySysType() + "/" + payInfo.getPayType());
        returnRefundInfo.setNotifyUrl("/order/refund/result/huifu");
        returnRefundInfo.setUserId(payInfo.getUserId());
        returnRefundInfo.setBizPayNo(payInfo.getBizPayNo());
        returnRefundInfo.setPaySysType(payInfo.getPaySysType());
        returnRefundInfo.setReqDate(refundInfoDto.getReqDate());
        boolean refundSuccess;
        // paypal支付，直接退款都不需要回调的
        // paypal、余额支付，直接退款都不需要回调的,只要有一个是需要回调则等回调
        //汇付支付退款 接口 微信 支付宝
        if (Objects.equals(payInfo.getPaySysType(), 0)) {
            logger.info("开始进行普通退款{}",returnRefundInfo);
            Boolean isSettled = false;
            List<String> refundOrderNumbers = refundInfoDto.getRefundOrderNumbers();
            List<Order> orderPayInfoByOrderNumber = orderService.getOrderPayInfoByOrderNumber(refundOrderNumbers);
            if (orderPayInfoByOrderNumber.size() >= 1) {
                Order order = orderPayInfoByOrderNumber.get(0);
                if (order.getIsSettled() == 1) {
                    //多个订单如果一个结算了就都结算了
                    isSettled = true;
                    logger.info(order.getOrderNumber() + "------->  此订单已经结算，所以走订单结算后退款");
                }
            }
            Map<String, Object> extendInfoMap = new HashMap<>();
            if(isSettled ){
                extendInfoMap = getRefundExtendIsSettledInfos(returnRefundInfo.getRefundSn());
            }else{
                extendInfoMap = getRefundExtendInfos(returnRefundInfo.getBizPayNo(),
                        "https://dlchm.cn/shop/apis" + returnRefundInfo.getNotifyUrl(),
                        returnRefundInfo.getRefundSn());
            }
            refundSuccess = payManager.doRefunds(returnRefundInfo,isSettled,extendInfoMap);
            //refundSuccess = payManager.doRefund(returnRefundInfo);
            //refundSuccess = payManager.doRefundHuifu(returnRefundInfo);
        } else {
            logger.info("开始进行通联退款{}",returnRefundInfo);
            refundSuccess = allinpayManager.doRefund(returnRefundInfo);
        }
        if (CollUtil.isNotEmpty(returnRefundInfo.getStockKeys())) {
            refundInfoDto.setStockKeys(returnRefundInfo.getStockKeys());
        } else {
            refundInfoDto.setStockKeys(new ArrayList<>());
        }
        // 支付宝有回调了，不需要这个
//        if (!Objects.equals(refundInfoDto.getOnlyRefund(), 1) && refundSuccess) {
//            for (RefundInfo refundInfo : refundInfoList) {
//                refundSuccess(refundInfo);
//                if (CollUtil.isNotEmpty(refundInfo.getStockKeys())) {
//                    refundInfoDto.getStockKeys().addAll(refundInfo.getStockKeys());
//                }
//            }
//        }
        return refundSuccess;
    }
    /**
     * 汇付 15天以后的退款 直接退款没有回调
     *
     * @param refundSn
     * @return
     */
    private Map<String, Object> getRefundExtendIsSettledInfos(String refundSn) {
        // 设置非必填字段
        Map<String, Object> extendInfoMap = new HashMap<>();

        //根据 退款编号查询退了多少钱，并且退款是多少钱
        OrderRefundDto orderRefund = getOrderRefundByRefundSn(refundSn);

        //查询供应商 汇付id
        JSONArray acct_infos = new JSONArray();
        String huifuId = shopDetailService.getShopDetailByShopId(orderRefund.getShopId()).getHuifuId();
        if (huifuId != null && !"".equals(huifuId)) {

            if(huifuId.equals(DemoTestConstants.DEMO_SYS_ID)){
                Double orderAmount = orderRefund.getOrderAmount();
                JSONObject acct_info = new JSONObject();
                acct_info.put("div_amt", BigDecimal.valueOf(orderAmount).setScale(2, RoundingMode.HALF_UP));
                acct_info.put("huifu_id", DemoTestConstants.DEMO_SYS_ID);
                acct_info.put("part_loan_amt", BigDecimal.valueOf(orderAmount).setScale(2, RoundingMode.HALF_UP));
                acct_infos.add(acct_info);
                extendInfoMap.put("acct_split_bunch", acct_infos);
            }else{
                //多商品退款
                Double supplierPrice = 0.00;
                for (OrderItem orderItem : orderRefund.getOrderItems()) {
                    if(orderItem.getRefundId() != null){
                        continue;
                    }
                    Sku sku = skuService.getSkuBySkuId(orderItem.getSkuId());
                    logger.info("sku的值是什么{}",sku.toString());
                    //一件商品可以有多个数量
                    supplierPrice += (sku.getSupplierPrice() * orderItem.getProdCount());
                }
                JSONObject acct_info_shop = new JSONObject();

                acct_info_shop.put("div_amt", BigDecimal.valueOf(supplierPrice).setScale(2, RoundingMode.HALF_UP));
                acct_info_shop.put("huifu_id", huifuId);
                acct_info_shop.put("part_loan_amt", BigDecimal.valueOf(supplierPrice).setScale(2, RoundingMode.HALF_UP));
                acct_infos.add(acct_info_shop);
                //剩下的由蒂爱喜承担
                Double orderAmount = orderRefund.getOrderAmount();
                BigDecimal orderAmountbig = new BigDecimal(orderAmount);
                BigDecimal supplierPricebig = new BigDecimal(supplierPrice);

                //BigDecimal求差
                BigDecimal dlcAmount = orderAmountbig.subtract(supplierPricebig).setScale(2, RoundingMode.HALF_UP);

                JSONObject acct_info = new JSONObject();
                acct_info.put("div_amt", dlcAmount);
                acct_info.put("huifu_id", DemoTestConstants.DEMO_SYS_ID);
                acct_info.put("part_loan_amt", dlcAmount);
                acct_infos.add(acct_info);
                extendInfoMap.put("acct_split_bunch", acct_infos);
            }
        }


        // 原交易微信支付宝的商户单号
        // extendInfoMap.put("org_party_order_id", "");
        // 原交易请求流水号
        // extendInfoMap.put("org_req_seq_id", "");
        // 分账对象
        // extendInfoMap.put("acct_split_bunch", getAcctSplitBunchRucan());
        // 聚合正扫微信拓展参数集合
        // extendInfoMap.put("wx_data", getWxData());
        // 数字货币扩展参数集合
        // extendInfoMap.put("digital_currency_data", getDigitalCurrencyData());
        // 补贴支付信息
        // extendInfoMap.put("combinedpay_data", getCombinedpayData());
        // 备注
        // extendInfoMap.put("remark", "");
        // 是否垫资退款
        // extendInfoMap.put("loan_flag", "");
        // 垫资承担者
        // extendInfoMap.put("loan_undertaker", "");
        // 垫资账户类型
        // extendInfoMap.put("loan_acct_type", "");
        // 安全信息
        // extendInfoMap.put("risk_check_data", getRiskCheckData());
        // 设备信息
        // extendInfoMap.put("terminal_device_data", getTerminalDeviceData());
        // 异步通知地址
        // extendInfoMap.put("notify_url", "");
        // 银联参数集合
        // extendInfoMap.put("unionpay_data", getUnionpayData());
        return extendInfoMap;
    }

    /**
     * 非必填字段 汇付15天以内的退款
     *
     * @return
     */
    private Map<String, Object> getRefundExtendInfos(String captureId, String url, String refundSn) {
        // 设置非必填字段
        Map<String, Object> extendInfoMap = new HashMap<>();
        // 原交易流水号
        extendInfoMap.put("org_req_seq_id", captureId);
        //汇付 退款需要回调地址
        extendInfoMap.put("notify_url", url);
        // 设备信息
        Map<String, String> deviceInfo = new HashMap<>();
        if (IpHelper.getIpAddr().equals("")) {
            deviceInfo.put("ip_addr", "127.0.0.1");
        } else {
            deviceInfo.put("ip_addr", IpHelper.getIpAddr());
        }
        extendInfoMap.put("risk_check_data", JSON.toJSONString(deviceInfo));
        //List<Map<String, String>> acct_infos = new ArrayList<>();

        //根据 退款编号查询退了多少钱，并且退款是多少钱
        OrderRefundDto orderRefund = getOrderRefundByRefundSn(refundSn);
        List<OrderItem> orderItems = orderRefund.getOrderItems();

        //查询供应商 汇付id
        JSONArray acct_infos = new JSONArray();
        String huifuId = shopDetailService.getShopDetailByShopId(orderRefund.getShopId()).getHuifuId();
        if (huifuId != null && !"".equals(huifuId)) {

            if(huifuId.equals(DemoTestConstants.DEMO_SYS_ID)){
                Double orderAmount = orderRefund.getOrderAmount();
                JSONObject acct_info = new JSONObject();
                acct_info.put("div_amt", BigDecimal.valueOf(orderAmount).setScale(2, RoundingMode.HALF_UP));
                acct_info.put("huifu_id", DemoTestConstants.DEMO_SYS_ID);
                acct_info.put("part_loan_amt", BigDecimal.valueOf(orderAmount).setScale(2, RoundingMode.HALF_UP));
                acct_infos.add(acct_info);
                extendInfoMap.put("acct_split_bunch", acct_infos);
            }else{
                //多商品退款
                Double supplierPrice = 0.00;
                for (OrderItem orderItem : orderItems) {
                    if(orderItem.getRefundId() != null){
                        continue;
                    }
                    Sku sku = skuService.getSkuBySkuId(orderItem.getSkuId());
                    logger.info("sku的值是什么{}",sku.toString());
                    //一件商品可以有多个数量
                    supplierPrice += (sku.getSupplierPrice() * orderItem.getProdCount());
                }
                JSONObject acct_info_shop = new JSONObject();

                acct_info_shop.put("div_amt", BigDecimal.valueOf(supplierPrice).setScale(2, RoundingMode.HALF_UP));
                acct_info_shop.put("huifu_id", huifuId);
                acct_info_shop.put("part_loan_amt", BigDecimal.valueOf(supplierPrice).setScale(2, RoundingMode.HALF_UP));
                acct_infos.add(acct_info_shop);
                //剩下的由蒂爱喜承担
                Double orderAmount = orderRefund.getOrderAmount();
                BigDecimal orderAmountbig = new BigDecimal(orderAmount);
                BigDecimal supplierPricebig = new BigDecimal(supplierPrice);

                //BigDecimal求差
                BigDecimal dlcAmount = orderAmountbig.subtract(supplierPricebig).setScale(2, RoundingMode.HALF_UP);

                JSONObject acct_info = new JSONObject();
                acct_info.put("div_amt", dlcAmount);
                acct_info.put("huifu_id", DemoTestConstants.DEMO_SYS_ID);
                acct_info.put("part_loan_amt", dlcAmount);
                acct_infos.add(acct_info);
                extendInfoMap.put("acct_split_bunch", acct_infos);
            }
        }

        // 原交易微信支付宝的商户单号
        // extendInfoMap.put("org_party_order_id", "");
        // 原交易请求流水号
        // extendInfoMap.put("org_req_seq_id", "");
        // 分账对象
        // extendInfoMap.put("acct_split_bunch", getAcctSplitBunchRucan());
        // 聚合正扫微信拓展参数集合
        // extendInfoMap.put("wx_data", getWxData());
        // 数字货币扩展参数集合
        // extendInfoMap.put("digital_currency_data", getDigitalCurrencyData());
        // 补贴支付信息
        // extendInfoMap.put("combinedpay_data", getCombinedpayData());
        // 备注
        // extendInfoMap.put("remark", "");
        // 是否垫资退款
        // extendInfoMap.put("loan_flag", "");
        // 垫资承担者
        // extendInfoMap.put("loan_undertaker", "");
        // 垫资账户类型
        // extendInfoMap.put("loan_acct_type", "");
        // 安全信息
        // extendInfoMap.put("risk_check_data", getRiskCheckData());
        // 设备信息
        // extendInfoMap.put("terminal_device_data", getTerminalDeviceData());
        // 异步通知地址
        // extendInfoMap.put("notify_url", "");
        // 银联参数集合
        // extendInfoMap.put("unionpay_data", getUnionpayData());
        return extendInfoMap;
    }


    public OrderRefundDto getOrderRefundByRefundSn(String refundSn) {

        OrderRefundDto orderRefundDto = orderRefundMapper.getOrderRefundByRefundSn(refundSn);
        if (orderRefundDto == null) {
            return null;
        }
        // 如果是单项退款,且订单状态为待发货，则退款数量为：主商品数量+赠品数量
        if (orderRefundDto.getRefundType().equals(RefundType.SINGLE.value()) && orderRefundDto.getStatus().equals(OrderStatus.PADYED.value())) {
            Integer prodNum = orderItemService.getOrderItemProdNum(orderRefundDto.getOrderItemId());
            orderRefundDto.setGoodsNum(prodNum);
        }
        // 如果是整单退款,判断一下能否进行平台介入,如果有其他正在进行的就不能进行
        List<OrderRefund> processingOrderRefunds = orderRefundMapper.getProcessingOrderRefundByOrderId(orderRefundDto.getOrderId());
        if(Objects.equals(orderRefundDto.getRefundType(),RefundType.ALL.value())) {
            orderRefundDto.setCanApplyRefund(CollectionUtil.isEmpty(processingOrderRefunds));
        } else {
            List<OrderRefund> filterOrderRefunds = processingOrderRefunds.stream().filter(orderRefund ->
                    Objects.equals(orderRefund.getOrderItemId(), 0L) || Objects.equals(orderRefund.getOrderItemId(), orderRefundDto.getOrderItemId())).toList();
            orderRefundDto.setCanApplyRefund(CollectionUtil.isEmpty(filterOrderRefunds));
        }
        //获取总数，如果为0则为全部
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderRefundDto.getOrderNumber()));
        if (orderRefundDto.getGoodsNum() == 0) {
            orderRefundDto.setGoodsNum(order.getProductNums());
        }
        orderRefundDto.setOrderMold(order.getOrderMold());
        // 判断退款单类型（1:整单退款,2:单个物品退款）
        getRefundTypeByOrderItem(orderRefundDto, 1);
        orderRefundDto.setIsCancel(true);
        // 目前运费不在提交时计算,所以都可以撤销
        // 查询平台介入信息
       // handleIntervention(orderRefundDto);
        return orderRefundDto;
    }
    /**
     * 判断退款单类型（1:整单退款,2:单个物品退款）
     * sysType,1.展示赠品信息，0.不展示
     */
    private void getRefundTypeByOrderItem(OrderRefundDto orderRefundDto, Integer sysType) {
        Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderId, orderRefundDto.getOrderId()).eq(Order::getShopId, orderRefundDto.getShopId()));
        orderRefundDto.setPlatformAmount(Arith.sub(order.getPlatformAmount(),order.getPlatformFreeFreightAmount()));
        orderRefundDto.setPlatformFreeFreightAmount(order.getPlatformFreeFreightAmount());
        List<OrderItem> orderItems = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderRefundDto.getOrderNumber()));
        if (Objects.equals(orderRefundDto.getRefundType(), RefundType.ALL.value())) {
            orderRefundDto.setRefundScore(orderItems.stream().mapToLong(OrderItem::getUseScore).sum());
            //放入赠品信息
            if (Objects.equals(sysType, 1)) {
                orderItemService.handleActivityOrderItem(orderItems,null);
            }
            orderRefundDto.setOrderItems(orderItems);
        } else {
            orderRefundDto.setFreightAmount(order.getFreightAmount());
            OrderItem item = orderItems.stream().filter(orderItem ->  Objects.equals(orderItem.getOrderItemId(),orderRefundDto.getOrderItemId())).toList().get(0);
            item.setProdCount(orderRefundDto.getGoodsNum());
            orderRefundDto.getOrderItems().add(item);

            orderRefundDto.setRefundScore(item.getUseScore());
            if (Objects.equals(sysType, 0)) {
                return;
            }
            // 处理一下赠品和组合商品子订单项
            Map<Long, List<OrderItem>> comboMap = orderItems.stream()
                    .filter(s -> Objects.equals(s.getActivityType(), OrderActivityType.COMBO_PROD.value()))
                    .collect(Collectors.groupingBy(OrderItem::getActivityId));
            item.setComboList(comboMap.get(item.getOrderItemId()));

            if(Objects.isNull(orderRefundDto.getReturnGiveawayIds())) {
                return;
            }
            List<String> itemIds = Arrays.asList(orderRefundDto.getReturnGiveawayIds().split(StrUtil.COMMA));
            List<OrderItem> giveawayOrderItems = new ArrayList<>();
            Map<Long, List<OrderItem>> giveawawMap = orderItems.stream()
                    .filter(s -> Objects.equals(s.getActivityType(), OrderActivityType.GIVEAWAY.value()))
                    .collect(Collectors.groupingBy(OrderItem::getActivityId));
            for (OrderItem orderItem : giveawawMap.get(item.getOrderItemId())) {
                if (!itemIds.contains(orderItem.getOrderItemId().toString())) {
                    continue;
                }
                giveawayOrderItems.add(orderItem);
            }
            item.setGiveawayList(giveawayOrderItems);
        }
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refundSuccess(RefundInfo refundInfo) {
        // 已经退款
        if (Objects.equals(refundInfo.getRefundStatus(), RefundStatusEnum.SUCCEED.value())) {
            return;
        }
        refundInfo.setCallbackContent(refundInfo.getCallbackContent());
        refundInfo.setCallbackTime(new Date());
        refundInfo.setRefundStatus(RefundStatusEnum.SUCCEED.value());
        refundInfoMapper.update(refundInfo, new LambdaUpdateWrapper<RefundInfo>().eq(RefundInfo::getRefundId, refundInfo.getRefundId()));
        //重复支付直接退款 不需要验证退款信息
        if(Objects.equals(refundInfo.getRefundType(), RefundKindEnum.REPEAT_PAY.value())) {
            return;
        }
        // 验证退款信息
        eventPublisher.publishEvent(new RefundInfoEvent(refundInfo));
        refundInfo.setStockKeys(refundInfo.getStockKeys());
    }

    @Override
    public AccountDetailVO getRefundAccountDetail(Date startTime, Date endTime, String shopName) {
        Integer paySysType = allinpayCompanyService.getIsAllinpay() ? PaySysType.ALLINPAY.value() : PaySysType.DEFAULT.value();
        AccountDetailVO accountDetailVO = refundInfoMapper.getRefundAccountDetail(startTime, endTime, shopName, paySysType);
        return getAccountDetailVO(accountDetailVO);
    }

    @Override
    public AccountDetailVO getPlatformRefundAccountDetail(Date startTime, Date endTime) {
        Integer paySysType = allinpayCompanyService.getIsAllinpay() ? PaySysType.ALLINPAY.value() : PaySysType.DEFAULT.value();
        AccountDetailVO platformRefundAccountDetail = refundInfoMapper.getPlatformRefundAccountDetail(startTime, endTime, paySysType);
        return getAccountDetailVO(platformRefundAccountDetail);
    }

    @Override
    public AccountDetailVO getAccountDetailVO(AccountDetailVO accountDetailVO) {
        if (Objects.isNull(accountDetailVO)){
            AccountDetailVO accountDetail = new AccountDetailVO();
            accountDetail.setWechatAmount(0.0);
            accountDetail.setAlipayAmount(0.0);
            accountDetail.setBalanceAmount(0.0);
            accountDetail.setPaypalAmount(0.0);
            accountDetail.setScoreCount(0L);
            accountDetail.setWechatPercent(0.00);
            accountDetail.setAlipayPercent(0.00);
            accountDetail.setBalancePercent(0.00);
            accountDetail.setPaypalPercent(0.00);
            accountDetail.setTotal(0.0);
            return accountDetail;
        } else {
            double wechatAmount = accountDetailVO.getWechatAmount();
            double alipayAmount = accountDetailVO.getAlipayAmount();
            double balanceAmount = accountDetailVO.getBalanceAmount();
            double paypalAmount = accountDetailVO.getPaypalAmount();
            double total = Arith.add(Arith.add(Arith.add(wechatAmount, alipayAmount), balanceAmount), paypalAmount);
            accountDetailVO.setTotal(total);
            accountDetailVO.setWechatPercent(Arith.div(wechatAmount, total,4));
            accountDetailVO.setAlipayPercent(Arith.div(alipayAmount, total,4));
            accountDetailVO.setBalancePercent(Arith.div(balanceAmount, total,4));
            accountDetailVO.setPaypalPercent(Arith.div(paypalAmount, total, 4));
            return accountDetailVO;
        }
    }

    @Override
    public IPage<ShopAccountVO> listRefundAccountDetail(PageParam<ShopAccountVO> page, CustomerReqParam accountSearchDTO) {
        Integer paySysType = allinpayCompanyService.getIsAllinpay() ? PaySysType.ALLINPAY.value() : PaySysType.DEFAULT.value();
        return refundInfoMapper.pageAllRefundAccount(page, accountSearchDTO.getStartTime(), accountSearchDTO.getEndTime(), accountSearchDTO.getShopName(), paySysType);
    }

    @Override
    public IPage<ShopAccountDetailVO> pageShopRefundAccountDetail(PageParam<ShopAccountDetailVO> page, CustomerReqParam customerReqParam) {
        Integer paySysType = allinpayCompanyService.getIsAllinpay() ? PaySysType.ALLINPAY.value() : PaySysType.DEFAULT.value();
        IPage<ShopAccountDetailVO> accountDetailPage;
        if (Objects.equals(customerReqParam.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            accountDetailPage = refundInfoMapper.pagePlatformRefundAccountDetail(page, customerReqParam.getStartTime(), customerReqParam.getEndTime(), paySysType);
        } else {
            accountDetailPage = refundInfoMapper.pageShopRefundAccountDetail(page, customerReqParam.getStartTime(), customerReqParam.getEndTime(), customerReqParam.getShopId(), paySysType);
        }
        return accountDetailPage;
    }

    @Override
    public List<ShopAccountDetailVO> listRefundAccountDetail(CustomerReqParam customerReqParam) {
        Integer paySysType = allinpayCompanyService.getIsAllinpay() ? PaySysType.ALLINPAY.value() : PaySysType.DEFAULT.value();
        return refundInfoMapper.listRefundAccountDetail(customerReqParam.getStartTime(), customerReqParam.getEndTime(), customerReqParam.getShopName(), paySysType);
    }

    @Override
    public void updateRefundStatus(List<RefundInfo> refundInfoList) {
        refundInfoMapper.updateRefundStatus(refundInfoList);
    }

    @Override
    public List<RefundInfo> listAliPayRefund() {
        return refundInfoMapper.listAliPayRefund();
    }

    @Override
    public RefundInfo getByRefundId(String refundId) {
        return refundInfoMapper.getByRefundId(refundId);
    }
}
